package org.jhotdraw.samples.phototemplate;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.AbstractButton;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JToolBar;
import javax.swing.JViewport;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.imgscalr.Scalr;
import org.jhotdraw.draw.AttributeKey;
import org.jhotdraw.draw.AttributeKeys;
import org.jhotdraw.draw.DefaultDrawingEditor;
import org.jhotdraw.draw.DefaultDrawingView;
import org.jhotdraw.draw.Drawing;
import org.jhotdraw.draw.DrawingEditor;
import org.jhotdraw.draw.DrawingView;
import org.jhotdraw.draw.Figure;
import org.jhotdraw.draw.QuadTreeDrawing;
import org.jhotdraw.draw.action.ButtonFactory;
import org.jhotdraw.draw.event.FigureAdapter;
import org.jhotdraw.draw.event.FigureEvent;
import org.jhotdraw.draw.io.ImageInputFormat;
import org.jhotdraw.draw.io.ImageOutputFormat;
import org.jhotdraw.draw.io.InputFormat;
import org.jhotdraw.draw.io.OutputFormat;
import org.jhotdraw.draw.io.SerializationInputOutputFormat;
import org.jhotdraw.draw.io.TextInputFormat;
import org.jhotdraw.draw.tool.DnDTracker;
import org.jhotdraw.draw.tool.SelectionTool;
import org.jhotdraw.samples.svg.SVGAttributeKeys;
import org.jhotdraw.samples.svg.figures.SVGImageFigure;
import org.jhotdraw.samples.svg.figures.SVGRectFigure;
import org.jhotdraw.samples.svg.figures.SVGTextAreaFigure;
import org.jhotdraw.samples.svg.figures.SVGTextFigure;
import org.jhotdraw.samples.svg.io.ImageMapOutputFormat;
import org.jhotdraw.samples.svg.io.SVGInputFormat;
import org.jhotdraw.samples.svg.io.SVGOutputFormat;
import org.jhotdraw.samples.svg.io.SVGZInputFormat;
import org.jhotdraw.samples.svg.io.SVGZOutputFormat;

/**
 *
 * @author Eliazar
 */
public class PanelRecord extends javax.swing.JPanel {

    private Map<String, File> mapTemplates;
    private DrawingEditor editor;
    private DefaultDrawingView view;
    private JToolBar tb;
    private Map<URI, JLabel> mapThumbailsToDropzone;    
    private Map<URI, JLabel> mapThumbailsOnTemplate;
    private Map<URI, URI> mapNewAndOldURI;
    private SVGRectFigure canvasRectangule;
    private final int resolutionToPrint = 300;
    private int resolutionOfScreen;
    private Map<Figure, List> figureParams;
    private final int sizeThumbnail = 70;
    private final String fileExtension = ".pro3d";

    /**
     * Creates new form PanelRecord
     */
    public PanelRecord() {
        initComponents();
        mapTemplates = new HashMap<String, File>();        
        tb = new javax.swing.JToolBar();
        resolutionOfScreen = java.awt.Toolkit.getDefaultToolkit().getScreenResolution();
        panelProgress.setVisible(false);
        
        JViewport viewport = new JViewport();                       
        viewport.setPreferredSize(new Dimension(100, 300));
        viewport.add(panelMiniPhoto);
        scrollPanelMiniPhoto.setViewportView(viewport);
        mapNewAndOldURI = new Hashtable<URI, URI>();
        loadFrameRecord();
        addListeners();
        loadTemplates();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        txtOS = new javax.swing.JTextField();
        btGetClientRecord = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        cmbTemplate = new javax.swing.JComboBox();
        btExport = new javax.swing.JButton();
        panelProgress = new javax.swing.JPanel();
        progressBar = new javax.swing.JProgressBar();
        jLabel3 = new javax.swing.JLabel();
        jSplitPane1 = new javax.swing.JSplitPane();
        panelRecord = new javax.swing.JPanel();
        panelScrollTemplate = new javax.swing.JScrollPane();
        scrollPanelMiniPhoto = new javax.swing.JScrollPane();
        panelMiniPhoto = new javax.swing.JPanel();

        jLabel1.setText("Ordem de Serviço:");

        btGetClientRecord.setText("Consultar");
        btGetClientRecord.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btGetClientRecordActionPerformed(evt);
            }
        });

        jLabel2.setText("Template:");

        cmbTemplate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmbTemplateActionPerformed(evt);
            }
        });

        btExport.setText("Exportar");
        btExport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btExportActionPerformed(evt);
            }
        });

        jLabel3.setText("jLabel3");

        javax.swing.GroupLayout panelProgressLayout = new javax.swing.GroupLayout(panelProgress);
        panelProgress.setLayout(panelProgressLayout);
        panelProgressLayout.setHorizontalGroup(
            panelProgressLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelProgressLayout.createSequentialGroup()
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        panelProgressLayout.setVerticalGroup(
            panelProgressLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(114, 114, 114)
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtOS, javax.swing.GroupLayout.PREFERRED_SIZE, 112, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btGetClientRecord)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmbTemplate, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btExport)
                .addContainerGap())
            .addComponent(panelProgress, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE)
                    .addComponent(txtOS, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btGetClientRecord)
                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmbTemplate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btExport))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panelProgress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        jSplitPane1.setDividerLocation(140);
        jSplitPane1.setDividerSize(10);

        panelRecord.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        javax.swing.GroupLayout panelRecordLayout = new javax.swing.GroupLayout(panelRecord);
        panelRecord.setLayout(panelRecordLayout);
        panelRecordLayout.setHorizontalGroup(
            panelRecordLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(panelScrollTemplate, javax.swing.GroupLayout.DEFAULT_SIZE, 793, Short.MAX_VALUE)
        );
        panelRecordLayout.setVerticalGroup(
            panelRecordLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(panelScrollTemplate, javax.swing.GroupLayout.DEFAULT_SIZE, 231, Short.MAX_VALUE)
        );

        jSplitPane1.setRightComponent(panelRecord);

        scrollPanelMiniPhoto.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        scrollPanelMiniPhoto.setToolTipText("Arraste e solte as imagens aqui");
        scrollPanelMiniPhoto.setMinimumSize(new java.awt.Dimension(100, 25));

        panelMiniPhoto.setMaximumSize(new java.awt.Dimension(100, 32767));
        panelMiniPhoto.setMinimumSize(new java.awt.Dimension(100, 0));
        panelMiniPhoto.setPreferredSize(new java.awt.Dimension(100, 272));

        javax.swing.GroupLayout panelMiniPhotoLayout = new javax.swing.GroupLayout(panelMiniPhoto);
        panelMiniPhoto.setLayout(panelMiniPhotoLayout);
        panelMiniPhotoLayout.setHorizontalGroup(
            panelMiniPhotoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 118, Short.MAX_VALUE)
        );
        panelMiniPhotoLayout.setVerticalGroup(
            panelMiniPhotoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 272, Short.MAX_VALUE)
        );

        scrollPanelMiniPhoto.setViewportView(panelMiniPhoto);

        jSplitPane1.setLeftComponent(scrollPanelMiniPhoto);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 948, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 237, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void updateSizeView(Dimension size) {
        JViewport viewport = new JViewport();
        view.setSize(size);
        // os 12px na largura e altura são para compensar as margens e padding utilizadas pelos paineis.
        viewport.setPreferredSize(new Dimension(Double.valueOf(size.getWidth() + 12).intValue(), Double.valueOf(size.getHeight() + 12).intValue()));
        viewport.add(view);
        panelScrollTemplate.setViewportView(viewport);
    }
    
    private void cmbTemplateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmbTemplateActionPerformed
        view.getDrawing().removeAllChildren();

        if (cmbTemplate.getSelectedIndex() > 0) {
            try {
                setCursor(new Cursor(Cursor.WAIT_CURSOR));
                figureParams = new HashMap<Figure, List>();
                File template = mapTemplates.get(cmbTemplate.getSelectedItem());
                BufferedReader br = new BufferedReader(new FileReader(template));
                String line = null;
                while ((line = br.readLine()) != null) {
                    if (line.startsWith("SIZE=")) {
                        line = line.replace("SIZE=", "");
                        addCanvas(line);
                    } else if (line.startsWith("REC=")) {
                        line = line.replace("REC=", "");
                        addDropZone(line);
                    } else if (line.startsWith("IMG=")) {
                        line = line.replace("IMG=", "");
                        addImage(line);
                    } else if (line.startsWith("TXT=")) {
                        line = line.replace("TXT=", "");
                        addText(line);
                    }
                }
                updateSizeView(new Dimension(Double.valueOf(canvasRectangule.getWidth()).intValue(), Double.valueOf(canvasRectangule.getHeight()).intValue()));
            } catch (Exception ex) {                
                view.getDrawing().removeAllChildren();
                figureParams = null;
                MessageDialog.showMessageFail(this, "O template não pode ser carregado. As informações descritas no arquivo do template estão descritas incorretamente.");
            } finally {
                setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
            }
        }
        System.gc();
    }//GEN-LAST:event_cmbTemplateActionPerformed

    private void addText(String line) throws Exception{
        List att = new ArrayList();
        String[] params = line.split(";");
        SVGTextAreaFigure textAreaFigure = new SVGTextAreaFigure(params[4]);
        java.awt.Font font = new java.awt.Font(params[5], Integer.parseInt(params[6]), Integer.parseInt(params[7]));
        Color color = new Color(Integer.parseInt(params[8]));
        textAreaFigure.set(AttributeKeys.FONT_FACE, font);
        textAreaFigure.set(AttributeKeys.TEXT_COLOR, color);
        textAreaFigure.set(AttributeKeys.FILL_COLOR, color);
        textAreaFigure.set(AttributeKeys.FONT_SIZE, (double) font.getSize());
        Rectangle2D.Double bound = new Rectangle2D.Double(Double.valueOf(params[0]), Double.valueOf(params[1]), Double.valueOf(params[2]), Double.valueOf(params[3]));
        att.add(bound);
        textAreaFigure.setBounds(new Rectangle2D.Double(UnitConv.mm2px(bound.x, resolutionOfScreen), UnitConv.mm2px(bound.y, resolutionOfScreen), UnitConv.mm2px(bound.width, resolutionOfScreen), UnitConv.mm2px(bound.height, resolutionOfScreen)));
        textAreaFigure.setSelectable(false);
        view.getDrawing().add(textAreaFigure);
        att.add(font);
        att.add(color);
        figureParams.put(textAreaFigure, att);
    }

    private void addImage(String line) throws Exception {        
        File file = null;
        List att = new ArrayList();
        String[] params = line.split(";");
        Rectangle2D.Double bound = new Rectangle2D.Double(Double.valueOf(params[0]), Double.valueOf(params[1]), Double.valueOf(params[2]), Double.valueOf(params[3]));
        SVGImageFigure img = new SVGImageFigure();
        img.setBounds(new Rectangle2D.Double(UnitConv.mm2px(bound.x, resolutionOfScreen), UnitConv.mm2px(bound.y, resolutionOfScreen), UnitConv.mm2px(bound.width, resolutionOfScreen), UnitConv.mm2px(bound.height, resolutionOfScreen)));
        img.setSelectable(false);
        file = new File(params[4]);
        img.setBufferedImage(ImageIO.read(file));
        view.getDrawing().add(img);
        att.add(bound);
        att.add(file);
        figureParams.put(img, att);        
    }

    private void addDropZone(String line) throws Exception {
        List att = new ArrayList();
        Map<AttributeKey, Object> attributes = new HashMap<AttributeKey, Object>();
        attributes.put(AttributeKeys.STROKE_COLOR, Color.black);
        attributes.put(AttributeKeys.STROKE_WIDTH, 2D);
        attributes.put(SVGAttributeKeys.FILL_OPACITY, 0D);
        String[] params = line.split(";");
        Rectangle2D.Double bound = new Rectangle2D.Double(Double.valueOf(params[0]), Double.valueOf(params[1]), Double.valueOf(params[2]), Double.valueOf(params[3]));
        att.add(bound);
        SVGRectFigure rec = new SVGRectFigure();
        rec.setBounds(new Rectangle2D.Double(UnitConv.mm2px(bound.x, resolutionOfScreen), UnitConv.mm2px(bound.y, resolutionOfScreen), UnitConv.mm2px(bound.width, resolutionOfScreen), UnitConv.mm2px(bound.height, resolutionOfScreen)));
        rec.setAttributes(attributes);
        rec.setSelectable(false);
        view.getDrawing().add(rec);
        figureParams.put(rec, att);
    }

    private void addCanvas(String line) throws Exception {
        List att = new ArrayList();
        Map<AttributeKey, Object> attributes = new HashMap<AttributeKey, Object>();
        attributes.put(AttributeKeys.STROKE_COLOR, Color.black);
        attributes.put(AttributeKeys.STROKE_WIDTH, 2D);
        attributes.put(SVGAttributeKeys.FILL_OPACITY, 0D);
        String[] params = line.split(";");
        Rectangle2D.Double bound = new Rectangle2D.Double(Double.valueOf(params[0]), Double.valueOf(params[1]), Double.valueOf(params[2]), Double.valueOf(params[3]));
        att.add(bound);
        canvasRectangule = new SVGRectFigure();
        canvasRectangule.setBounds(new Rectangle2D.Double(UnitConv.mm2px(bound.x, resolutionOfScreen), UnitConv.mm2px(bound.y, resolutionOfScreen), UnitConv.mm2px(bound.width, resolutionOfScreen), UnitConv.mm2px(bound.height, resolutionOfScreen)));
        canvasRectangule.setSelectable(false);
        canvasRectangule.setAttributes(attributes);
        view.getDrawing().add(canvasRectangule);
        figureParams.put(canvasRectangule, att);
    }

    private void btExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btExportActionPerformed
        JFileChooser chooser = new JFileChooser();
        chooser.setDialogTitle("Exportando prontuário");
        chooser.addChoosableFileFilter(new FileNameExtensionFilter("arquivos png", "png"));
        chooser.addChoosableFileFilter(new FileNameExtensionFilter("arquivos pdf", "pdf"));
        if (chooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
            try {
                setCursor(new Cursor(Cursor.WAIT_CURSOR));
                if (chooser.getFileFilter() != null) {
                    if (chooser.getFileFilter().getDescription().contains("png")) {                   
                        File fileTemp = chooser.getSelectedFile();
                        File file;
                        if (!fileTemp.getName().endsWith(".png")) {
                            file = new File(fileTemp.getPath() + ".png");
                            file.getPath();
                        } else {
                            file = fileTemp;
                        }
                        view.getDrawing().remove(canvasRectangule);
                        exportToImage(file);                        
                        MessageDialog.showMessageOk(this);                    
                    } else {                    
                        File fileTemp = chooser.getSelectedFile();
                        File file;
                        if (!fileTemp.getName().endsWith(".pdf")) {
                            file = new File(fileTemp.getPath() + ".pdf");
                            file.getPath();
                        } else {
                            file = fileTemp;
                        }
                        view.getDrawing().remove(canvasRectangule);
                        exportToPDF(file);                        
                        MessageDialog.showMessageOk(this);                    
                    }
                }
            } catch (Exception e) {
                MessageDialog.showMessageFail(this, "Um error ocorreu durante a exportação do template. A exportação foi abortada.");
            } 
            if(!view.getDrawing().contains(canvasRectangule)) {
                view.getDrawing().add(canvasRectangule);
                canvasRectangule.setSelectable(false);
            }
            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        }
    }//GEN-LAST:event_btExportActionPerformed

    public void removeTempFile() {
        if(mapNewAndOldURI != null && !mapNewAndOldURI.isEmpty()) {
            File file;
            for (URI uri : mapNewAndOldURI.keySet()) {
                try {
                    file = new File(uri);
                    file.delete();
                }catch(Exception exception)  {
                    System.out.println("O arquivo temporário (" + uri.getPath() + ") não pode ser removido.");
                }
            }
        }
    }
    
    private void btGetClientRecordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btGetClientRecordActionPerformed
        try {
            Date today = Calendar.getInstance().getTime();
            DateFormat df = new SimpleDateFormat("yyyyMMdd");
            String password = Utilities.getProperty(Utilities.KEY.SENHA_WEB_SERVICE) + df.format(today);
            String token = Utilities.generateMD5(password);
            String webService = Utilities.getProperty(Utilities.KEY.URL_SERVICE);
            String uriBase = webService + "/" + token + "/" + txtOS.getText();
            WebServiceClient client = new WebServiceClient(uriBase);
            Map<String, String> mapElements = client.getRecordMap();
            if (mapElements.isEmpty()) {
                MessageDialog.showMessageFail(this, "Nenhuma ordem de serviço foi encontrado com o número informado.");
            } else {
                System.out.println(mapElements);
                insertPacientInformationInTemplate(mapElements);
            }
        } catch (WebServiceException exception) {
            MessageDialog.showMessageFail(this, exception.getMessage());
        } catch (Exception ex) {
            MessageDialog.showMessageFail(this, "Erro durante a execução do serviço web. Contacte o administrado do sistema.");
        }
    }//GEN-LAST:event_btGetClientRecordActionPerformed

    private void insertPacientInformationInTemplate(Map<String, String> map) {
        String label;
        for (Figure figure : view.getDrawing().getChildren()) {
            if (figure instanceof SVGTextAreaFigure) {
                label = ((SVGTextAreaFigure) figure).getText().replace("[", "").replace("]", "");
                if (map.containsKey(label)) {
                    ((SVGTextAreaFigure) figure).setText(map.get(label));
                }
            }
        }
        view.getDrawing().willChange();
    }

    private void exportToPDF(File file) throws Exception {
        Rectangle2D.Double boundInMM = (Rectangle2D.Double) figureParams.get(canvasRectangule).get(0);
        Document document = new Document();
        OutputStream outputStream = null;
        try {            
            //document.setPageSize(new Rectangle((float) UnitConv.mm2px(boundInMM.width, resolutionToPrint), (float) UnitConv.mm2px(boundInMM.height, resolutionToPrint)));
            document.setPageSize(new Rectangle((float)UnitConv.mm2pt(boundInMM.width), (float)UnitConv.mm2pt(boundInMM.height)));
            document.setMargins(0, 0, 0, 0);
            outputStream = new FileOutputStream(file);
            PdfWriter.getInstance(document, outputStream);
            document.open();
            com.itextpdf.text.Image img;
            BufferedImage bi = createImageToExport(UnitConv.IN2PT);   
            ImageUtils.writeImagePNG(new File(file.getPath().replace(".pdf", ".png")), bi, UnitConv.IN2PT);
            img = com.itextpdf.text.Image.getInstance(ImageUtils.bufferedImageToBytes(bi));
            document.add(img);
                       
            document.close();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void exportToImage(File file) throws IOException {        
        BufferedImage image = createImageToExport(resolutionToPrint);
        ImageUtils.writeImagePNG(file, image, resolutionToPrint);        
    }

   private BufferedImage createImageToExport(int resolutionToExport) throws IOException {
        Rectangle2D.Double boundInMM = (Rectangle2D.Double) figureParams.get(canvasRectangule).get(0);
        Rectangle2D.Double boundInPx = new Rectangle2D.Double(UnitConv.mm2px(boundInMM.x, resolutionToExport), UnitConv.mm2px(boundInMM.y, resolutionToExport), UnitConv.mm2px(boundInMM.width, resolutionToExport), UnitConv.mm2px(boundInMM.height, resolutionToExport));

        BufferedImage image = new BufferedImage((int) boundInPx.width, (int) boundInPx.height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        g2.setColor(Color.WHITE);
        g2.fill(boundInPx);

        for (Figure figure : view.getDrawing().getChildren()) {
            if (figure instanceof SVGImageFigure && !(figure instanceof SVGImageFigurePhotoTemplate)) {
                boundInMM = (Rectangle2D.Double) figureParams.get(figure).get(0);
                boundInPx = new Rectangle2D.Double(UnitConv.mm2px(boundInMM.x, resolutionToExport), UnitConv.mm2px(boundInMM.y, resolutionToExport), UnitConv.mm2px(boundInMM.width, resolutionToExport), UnitConv.mm2px(boundInMM.height, resolutionToExport));
                BufferedImage bi = Scalr.resize(ImageIO.read((File) figureParams.get(figure).get(1)), (int) boundInPx.width, (int) boundInPx.height);
                g2.drawImage(bi, (int)boundInPx.x, (int)boundInPx.y,(int)boundInPx.width, (int)boundInPx.height, null);                
            } else if (figure instanceof SVGImageFigurePhotoTemplate) {
                boundInPx = new Rectangle2D.Double(UnitConv.px2px(figure.getDrawingArea().x, resolutionOfScreen, resolutionToExport), UnitConv.px2px(figure.getDrawingArea().y, resolutionOfScreen, resolutionToExport), UnitConv.px2px(figure.getDrawingArea().width, resolutionOfScreen, resolutionToExport), UnitConv.px2px(figure.getDrawingArea().height, resolutionOfScreen, resolutionToExport));
                BufferedImage bi = ImageIO.read(new File(((SVGImageFigurePhotoTemplate) figure).getImageUri()));
                bi = Scalr.resize(bi, (int) boundInPx.width, (int) boundInPx.height);
                g2.drawImage(bi, (int) boundInPx.x, (int) boundInPx.y, null);
            } else if (figure instanceof SVGTextAreaFigure) {
                SVGTextAreaFigure textAreaFigure = (SVGTextAreaFigure) figure;
                boundInMM = (Rectangle2D.Double) figureParams.get(figure).get(0);
                boundInPx = new Rectangle2D.Double(UnitConv.mm2px(boundInMM.x, resolutionToExport), UnitConv.mm2px(boundInMM.y, resolutionToExport), UnitConv.mm2px(boundInMM.width, resolutionToExport), UnitConv.mm2px(boundInMM.height, resolutionToExport));
                float newHeight = ((float) textAreaFigure.getDrawingArea().height) / resolutionOfScreen * resolutionToExport;
                double newFontSize = textAreaFigure.getFont().getSize2D() * newHeight / textAreaFigure.getDrawingArea().height;
                java.awt.Font newFont = textAreaFigure.getFont().deriveFont((float) newFontSize);
                g2.setColor(textAreaFigure.getTextColor());
                g2.setFont(newFont);                                
                FontRenderContext frc = g2.getFontRenderContext();
                FontMetrics metrics = g2.getFontMetrics(newFont);   
                TextLayout tl = new TextLayout(textAreaFigure.getText(), newFont, frc);                
                tl.draw(g2, (float) boundInPx.x, (float) (boundInPx.y + (metrics.getHeight() - metrics.getDescent())));               
            }
        }
        return image;
   }

    

    private void loadFrameRecord() {
        editor = new DefaultDrawingEditor();
        view = new DefaultDrawingView();
        view.setDrawing(createDrawing());
        editor.add(view);
        final SelectionTool selectionTool = new SelectionTool();
        selectionTool.setDragTracker(new DnDTracker());
        ButtonFactory.addSelectionToolTo(tb, editor, selectionTool);       
        new DropTarget(panelMiniPhoto, new DragDropFileListener());
        updateSizeView(new Dimension(800, 600));
    }

    private void addListeners() {
        view.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                if (e.getButton() == MouseEvent.BUTTON3) {
                    if (view.getDrawing().contains(new Point2D.Double(e.getX(), e.getY()))) {

                        ThumbnailDialog dialog = new ThumbnailDialog(null, true, mapThumbailsToDropzone);
                        dialog.setLocationRelativeTo(null);
                        dialog.setVisible(true);
                        if (dialog.getSelectedURIs() != null) {                            
                            try {
                                updateMapsFigure(dialog.getSelectedURIs());
                                Rectangle2D.Double drawingArea = getDrawingArea(e.getPoint());
                                BufferedImage bi;
                                URI selectedURI;
                                if(dialog.getSelectedURIs()[1] != null) {
                                    selectedURI = dialog.getSelectedURIs()[1];
                                }else {
                                    selectedURI = dialog.getSelectedURIs()[0];                                    
                                }
                                bi = ImageIO.read(new File(selectedURI));
                                bi = Scalr.resize(bi, (int)drawingArea.width, (int) drawingArea.height);
                                SVGImageFigure figure = new SVGImageFigurePhotoTemplate(selectedURI, drawingArea.x, drawingArea.y, drawingArea.width, drawingArea.height);
                                figure.addFigureListener(new FigureListerPhotoTemplate());
                                figure.setBufferedImage(bi);
                                view.getDrawing().add(figure);
                                figure.setSelectable(true);
                                updatePanelThumbnail();                                                               
                            } catch (IOException ex) {
                                Logger.getLogger(PanelRecord.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }                        
                    }
                }
            }

            private Rectangle2D.Double getDrawingArea(Point point) {
                for (Figure fg : view.getDrawing().getChildren()) {
                    if (fg instanceof SVGRectFigure && fg != canvasRectangule && fg.getDrawingArea().contains(point.getX(), point.getY())) {
                        return fg.getDrawingArea();
                    }
                }
                return null;
            }
        });
    }
    
    private void loadTemplates() {
        mapTemplates = new HashMap<String, File>();
        cmbTemplate.addItem("- selecione -");
        cmbTemplate.setSelectedIndex(0);
        String templatePath = Utilities.getProperty(Utilities.KEY.DIR_TEMPLATES);
        if (templatePath == null || templatePath.equals("")) {
            MessageDialog.showMessageFail(this, "Informe o diretório em que se encontram os templates, na opção Parâmetros do menu Configuração.");
        } else {
            File templateDir = new File(templatePath);
            for (File file : templateDir.listFiles()) {
                if(file.getName().endsWith(fileExtension)) {
                    mapTemplates.put(file.getName().replace(fileExtension, ""), file);
                    cmbTemplate.addItem(file.getName().replace(fileExtension, ""));
                }
            }
        }
    }

    private Drawing createDrawing() {
        Drawing drawing = new QuadTreeDrawing();
        LinkedList<InputFormat> inputFormats = new LinkedList<InputFormat>();
        inputFormats.add(new SVGZInputFormat());
        inputFormats.add(new SVGInputFormat());
        inputFormats.add(new ImageInputFormat(new SVGImageFigure(), "PNG", "Portable Network Graphics (PNG)", "png", "image/png"));
        inputFormats.add(new ImageInputFormat(new SVGImageFigure(), "JPG", "Joint Photographics Experts Group (JPEG)", "jpg", "image/jpg"));
        inputFormats.add(new ImageInputFormat(new SVGImageFigure(), "GIF", "Graphics Interchange Format (GIF)", "gif", "image/gif"));
        inputFormats.add(new TextInputFormat(new SVGTextFigure()));
        inputFormats.add(new SerializationInputOutputFormat());
        drawing.setInputFormats(inputFormats);

        LinkedList<OutputFormat> outputFormats = new LinkedList<OutputFormat>();
        outputFormats.add(new SVGOutputFormat());
        outputFormats.add(new SVGZOutputFormat());
        outputFormats.add(new ImageOutputFormat());
        outputFormats.add(new ImageOutputFormat("JPG", "Joint Photographics Experts Group (JPEG)", "jpg", BufferedImage.TYPE_INT_RGB));
        outputFormats.add(new ImageOutputFormat("BMP", "Windows Bitmap (BMP)", "bmp", BufferedImage.TYPE_BYTE_INDEXED));
        outputFormats.add(new ImageMapOutputFormat());
        outputFormats.add(new SerializationInputOutputFormat());
        drawing.setOutputFormats(outputFormats);

        return drawing;
    }             

    private void updateMapsFigure(URI[] selectedURIs) {
        JLabel label = mapThumbailsToDropzone.get(selectedURIs[0]);        
        mapThumbailsOnTemplate.put(selectedURIs[0], label);
        mapThumbailsToDropzone.remove(selectedURIs[0]);
        if(selectedURIs[1] != null) {            
            mapNewAndOldURI.put(selectedURIs[1], selectedURIs[0]);
        }        
    }
    
    private void updatePanelThumbnail() {
        panelMiniPhoto.removeAll();
        GridBagConstraints gbcPanelTumbnails = getGridBagConstraints();
        for (URI uri1 : mapThumbailsToDropzone.keySet()) {
            panelMiniPhoto.add(mapThumbailsToDropzone.get(uri1), gbcPanelTumbnails);
            gbcPanelTumbnails.gridy = panelMiniPhoto.getComponents().length;
        }
        
        JViewport viewport = new JViewport();
        viewport.setPreferredSize(new Dimension(100, panelMiniPhoto.getComponents().length * sizeThumbnail));
        viewport.add(panelMiniPhoto);
        scrollPanelMiniPhoto.setViewportView(viewport);
        
        panelMiniPhoto.invalidate();
        panelMiniPhoto.validate();
    }       
    
    private GridBagConstraints getGridBagConstraints() {
        GridBagConstraints gbcPanelTumbnails = new GridBagConstraints();
        gbcPanelTumbnails.insets = new Insets(2, 2, 2, 2);
        gbcPanelTumbnails.gridx = 0;
        if(panelMiniPhoto != null && panelMiniPhoto.getComponents() != null) {
            gbcPanelTumbnails.gridy = panelMiniPhoto.getComponents().length;
        }else {
            gbcPanelTumbnails.gridy = 0;
        }
        return gbcPanelTumbnails;
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btExport;
    private javax.swing.JButton btGetClientRecord;
    private javax.swing.JComboBox cmbTemplate;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JPanel panelMiniPhoto;
    private javax.swing.JPanel panelProgress;
    private javax.swing.JPanel panelRecord;
    private javax.swing.JScrollPane panelScrollTemplate;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JScrollPane scrollPanelMiniPhoto;
    private javax.swing.JTextField txtOS;
    // End of variables declaration//GEN-END:variables

    private class FigureListerPhotoTemplate extends  FigureAdapter {

        @Override
        public void figureRemoved(FigureEvent e) {
            URI removedURI = ((SVGImageFigurePhotoTemplate) e.getFigure()).getImageUri();
            if(mapNewAndOldURI.containsKey(removedURI)) {
                URI temp = removedURI;
                removedURI = mapNewAndOldURI.get(removedURI);
                mapNewAndOldURI.remove(temp);
            }
            mapThumbailsToDropzone.put(removedURI, mapThumbailsOnTemplate.get(removedURI));            
            mapThumbailsOnTemplate.remove(removedURI);               
            updatePanelThumbnail();
        }       
    }
        
    protected static class SelectionToolButtonHandler extends MouseAdapter {

        private DrawingEditor editor;
        private boolean wasSelectedOnPressed = false;

        public SelectionToolButtonHandler(DrawingEditor editor) {
            this.editor = editor;
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if (wasSelectedOnPressed) {
                DrawingView view = editor.getActiveView();
                if (view != null) {
                    view.setHandleDetailLevel(view.getHandleDetailLevel() + 1);
                }
            }
        }

        @Override
        public void mousePressed(MouseEvent e) {
            // Note: we blindly assume here that selection changes occur on mouse release!!
            wasSelectedOnPressed = ((AbstractButton) e.getSource()).isSelected();
        }
    }

    private class DragDropFileListener extends DropTarget {       
       
        @Override
        public void drop(DropTargetDropEvent event) {
            // Accept copy drops
            event.acceptDrop(DnDConstants.ACTION_COPY);

            // Get the transfer which can provide the dropped item data
            Transferable transferable = event.getTransferable();

            // Get the data formats of the dropped item
            DataFlavor[] flavors = transferable.getTransferDataFlavors();

            // Loop through the flavors                 
            List<URI> figures = new ArrayList<URI>();

            for (DataFlavor flavor : flavors) {
                try {
                    // If the drop items are files
                    if (flavor.isFlavorJavaFileListType()) {
                        // Get all of the dropped files
                        List files = (List) transferable.getTransferData(flavor);
                        loadFilesToDropZone(files);                        
                    }
                } catch (Exception e) {
                    // Print out the error stack
                    e.printStackTrace();
                }
            }
            // Inform that the drop is complete
            event.dropComplete(true);
        }

        private void loadFilesToDropZone(List files) {
            if(mapThumbailsToDropzone == null) {
                mapThumbailsToDropzone = new HashMap<URI, JLabel>();
                mapThumbailsOnTemplate = new HashMap<URI, JLabel>();                
                panelMiniPhoto.setLayout(new GridBagLayout());                                                
            }else {
                // removendo os arquivos que já foram carregados
                File file;
                List newList = new ArrayList();
                for (Object object : files) {
                    file = (File) object;
                    if(!mapThumbailsToDropzone.containsKey(file.toURI()) && !mapThumbailsOnTemplate.containsKey(file.toURI())) {
                        newList.add(file);
                    }
                }                              
                files = newList;
            }
            final LoadFilesWorker worker = new LoadFilesWorker(files, mapThumbailsToDropzone, panelMiniPhoto, scrollPanelMiniPhoto, panelProgress);
            worker.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent event) {
                if (event.getPropertyName().equals("progress")) {                                        
                    progressBar.setValue((Integer) event.getNewValue());
                } else if (event.getPropertyName().equals("state")) {
                    if (((SwingWorker.StateValue)event.getNewValue()).equals(SwingWorker.StateValue.DONE)) {
                        panelProgress.setVisible(false);                        
                    } else if (((SwingWorker.StateValue)event.getNewValue()).equals(SwingWorker.StateValue.STARTED)) {                        
                        panelProgress.setVisible(true);
                        progressBar.setVisible(true);
                        progressBar.setMinimum(0);
                        progressBar.setMaximum(100);
                    } else if (event.getNewValue().equals("pending")) {                        
                    }
                }
            }});  
            worker.execute();
        }
    }
    
    
}
